// logger.cpp
#include "logger.h"
#include <iomanip>
#include <ctime>
#include <sstream>
#include <fstream>
#include <cstdlib>
#include <iostream>
#include <filesystem>
#include <QDir>
#include <csignal>
#include <execinfo.h>
#include <unistd.h>

bool g_logTrackEnabled = false;
namespace fs = std::filesystem;

LogStream::LogStream(LogLevel level) : logLevel(level) {}

LogStream::~LogStream() {
    Logger::getInstance().log(logLevel, buffer.str());
}

Logger::Logger(QObject *parent) : QObject(parent){


    rotateLogs(logDirectory, logmaxFiles);
    //openLogFile();
}

Logger::~Logger() {
    if (logFile.is_open()) {
        logFile.close();
    }
}

Logger& Logger::getInstance() {
    static Logger instance;
    return instance;
}

void Logger::setLogDirectory(const std::string& directory) {

    //沒有使用 防盜Log裡面了
    // std::lock_guard<std::mutex> lock(mtx);
    // logDirectory = directory;
    // if (!fs::exists(logDirectory)) {
    //     fs::create_directories(logDirectory);
    // }
    // openLogFile();
}

void Logger::openLogFile() {
    QString qLogDirectory = QString::fromStdString(logDirectory);

    QDir dir(qLogDirectory);

    // 检查目录是否存在
    if (!dir.exists()) {
        // 如果目录不存在，则创建它
        if (dir.mkpath(".")) {
            std::cout << "Directory created successfully: " << logDirectory << std::endl;
        } else {
            std::cerr << "Failed to create directory: " << logDirectory << std::endl;
        }
    } else {
        std::cout << "Directory already exists: " << logDirectory << std::endl;
    }


    std::vector<int> indices;
    for (const auto& entry : fs::directory_iterator(logDirectory)) {
        std::string filename = entry.path().filename().string();
        if (filename.find("_") != std::string::npos && filename.find(".log") != std::string::npos) {
            try {
                int index = std::stoi(filename.substr(0, filename.find("_")));
                indices.push_back(index);
            } catch (const std::exception&) {
                // 忽略无法解析的文件名
            }
        }
    }

    int newIndex = indices.empty() ? 0 : (*std::max_element(indices.begin(), indices.end()) + 1);

    std::ostringstream oss;
    std::time_t t = std::time(nullptr);
    std::tm* tm = std::localtime(&t);
    oss << newIndex << "_" << std::put_time(tm, "%Y-%m-%d_%H-%M-%S") << ".log";
    logFileName = logDirectory + oss.str();

    logFile.open(logFileName, std::ios::out | std::ios::app);
    if (!logFile.is_open()) {
        std::cerr << "Could not open log file: " << logFileName << std::endl;
    } else {
        std::cout << "Log file opened: " << logFileName << std::endl;  // 调试信息
    }
}

std::string Logger::getCurrentTimeStamp() {
    std::ostringstream oss;
    std::time_t t = std::time(nullptr);
    std::tm* tm = std::localtime(&t);
    oss << std::put_time(tm, "%Y-%m-%d %H:%M:%S");
    return oss.str();
}

std::string Logger::getCurrentMMTimeStamp() {
    // 获取当前时间点
    auto now = std::chrono::system_clock::now();

    // 计算当前秒内的毫秒数
    auto milliseconds = std::chrono::duration_cast<std::chrono::milliseconds>(
                            now.time_since_epoch()) % std::chrono::seconds(1);

    // 转换为 time_t 格式
    std::time_t t = std::chrono::system_clock::to_time_t(now);

    // 转换为本地时间
    std::tm tm;
#ifdef _WIN32
    localtime_s(&tm, &t); // Windows 平台
#else
    localtime_r(&t, &tm); // POSIX 平台
#endif

    // 格式化输出，仅显示分钟、秒和毫秒
    std::ostringstream oss;
    oss << std::setfill('0') << std::setw(2) << tm.tm_min << ':'   // MM
        << std::setfill('0') << std::setw(2) << tm.tm_sec << '.'; // SS.

    // 添加毫秒部分
    oss << std::setfill('0') << std::setw(3) << milliseconds.count(); // mmm

    return oss.str();
}

void Logger::log(LogLevel level, const std::string& message) {
    std::string timestamp = getCurrentTimeStamp();
    std::string levelStr;

    switch (level) {
    case LogLevel::Debug: levelStr = "Debug"; break;
    case LogLevel::Info: levelStr = "Info"; break;
    case LogLevel::Warning: levelStr = "Warning"; break;
    case LogLevel::Error: levelStr = "Error"; break;
    case LogLevel::Fatal: levelStr = "Fatal"; break;
    }

    std::string formattedMessage = "[" + timestamp + "] [" + levelStr + "] " + message;

    {
        std::lock_guard<std::mutex> lock(mtx);
        if (logFile.is_open()) {
            logFile << formattedMessage << std::endl;
            logFile.flush();  // 确保内容写入文件
        } else {
            std::cerr << "Log file is not open: " << logFileName << std::endl;  // 调试信息
        }
    }

    // 显示到终端
    // std::cout << "[" << levelStr << "] " <<  "[" << getCurrentMMTimeStamp() << "] " << message << std::endl;

    std::cout << "[" << levelStr << "] " <<  message << std::endl;

    if (static_cast<int>(level) >= signalThreshold_) {
        emit logOutputSignal(static_cast<int>(level), QString::fromStdString(formattedMessage));
    }

    // 如果文件大小超过最大值，进行日志归档
    // if (logFile.tellp() >= static_cast<std::streampos>(maxLogSize)) {
    //     rotateLogs(logDirectory, logmaxFiles);
    // }
}

void Logger::rotateLogs(const std::string& directory, size_t maxFiles) {
    std::lock_guard<std::mutex> lock(mtx);

    QDir dir(QString::fromStdString(directory));
    if (!dir.exists()) {
        // 如果不存在则创建路径
        if (dir.mkpath(".")) {
            qDebug() << "Directory 'master/logs' created successfully.";
        } else {
            qDebug() << "Failed to create directory 'master/logs'.";
        }
    } else {
        qDebug() << "Directory 'master/logs' already exists.";
    }

    if(logFile.is_open())
        logFile.close();
    // 获取所有日志文件
    std::vector<fs::path> logs;
    for (const auto& entry : fs::directory_iterator(directory)) {
        if (entry.path().extension() == ".log") {
            logs.push_back(entry.path());
        }
    }

    // 按照文件名中的索引进行排序，并删除无法解析的文件
    logs.erase(std::remove_if(logs.begin(), logs.end(), [](const fs::path& path) {
                   std::string filename = path.filename().string();
                   std::string indexStr = filename.substr(0, filename.find("_"));
                   bool isValid = std::all_of(indexStr.begin(), indexStr.end(), ::isdigit);
                   if (!isValid) {
                       fs::remove(path);  // 删除无法解析的文件
                   }
                   return !isValid;
               }), logs.end());

    std::sort(logs.begin(), logs.end(), [](const fs::path& a, const fs::path& b) {
        int indexA = std::stoi(a.filename().string().substr(0, a.filename().string().find("_")));
        int indexB = std::stoi(b.filename().string().substr(0, b.filename().string().find("_")));
        return indexA < indexB;
    });

    // 如果日志文件超过maxFiles数量，删除最旧的文件
    if (logs.size() > maxFiles) {
        for (size_t i = 0; i < logs.size() - maxFiles; ++i) {
            fs::remove(logs[i]);
        }
    }

    openLogFile();
}

void Logger::installQtMessageHandler() {
    qInstallMessageHandler(qtMessageHandler);
}

void Logger::setsignalThreshold(int signalThreshold)
{
    LogDebug << "Attempting to Logger::setsignalThreshold :" << signalThreshold_;
    //LogDebug << "present Logger::setsignalThreshold :" << signalThreshold;
    if(signalThreshold_ != signalThreshold)
    {
        signalThreshold_ = signalThreshold;
        LogDebug << "Successful Logger::setsignalThreshold :" << signalThreshold_;
        emit signalThresholdChanged();
    }
}

void Logger::qtMessageHandler(QtMsgType type, const QMessageLogContext& context, const QString& msg) {
    std::string formattedMsg;

    switch (type) {
    case QtDebugMsg:
        formattedMsg = msg.toStdString();
        Logger::getInstance().log(LogLevel::Debug, formattedMsg);
        break;
    case QtInfoMsg:
        formattedMsg = msg.toStdString();
        Logger::getInstance().log(LogLevel::Info, formattedMsg);
        break;
    case QtWarningMsg:
        formattedMsg = msg.toStdString();
        Logger::getInstance().log(LogLevel::Warning, formattedMsg);
        break;
    case QtCriticalMsg:
        formattedMsg = msg.toStdString();
        Logger::getInstance().log(LogLevel::Error, formattedMsg);
        abort();
        break;
    case QtFatalMsg:
        formattedMsg = msg.toStdString();
        Logger::getInstance().log(LogLevel::Fatal, formattedMsg);
        abort();
    }
}
void signalHandler(int signal) {
    qCritical() << "Received signal: " << signal ;

    // 获取调用栈
    void *array[10];
    size_t size = backtrace(array, 10);
    char **messages = backtrace_symbols(array, size);
    for (size_t i = 0; i < size; ++i) {
        qCritical() << messages[i] ;
    }

}

void customTerminateHandler() {
    static bool triedThrow = false;
    try {
        if (!triedThrow) {
            triedThrow = true;
            throw;  // 重新抛出当前的异常
        }
    } catch (const std::exception& e) {
        qCritical() << "Terminate called after throwing an exception: " << e.what();
    } catch (...) {
        qCritical() << "Terminate called after throwing an unknown exception.";
    }
    std::abort();  // 终止程序
}

int testLogger()
{

    // 安装 Qt 消息处理程序
    Logger::getInstance().installQtMessageHandler();
    //Logger::getInstance().setLogDirectory("master/log");
    static QtLogStream qCriticalStream(QtCriticalMsg);
    std::cerr.rdbuf(&qCriticalStream);  // 重定向 std::cerr 到 qCritical

    // 使用不同等级记录日志
    LogDebug << "-----------Starting the application...------------------";
    signal(SIGSEGV, signalHandler);  // 捕获段错误
    signal(SIGABRT, signalHandler);  // 捕获异常中止
    std::set_terminate(customTerminateHandler);
    return 0;
}
